---
title: Subscriptions
description: How Unkey uses Stripe subscriptions
---

Our Stripe billing integration is designed with several important objectives:

1. **Calendar Month Alignment**

   - All billing cycles align with calendar months (1st to end of month)
   - Provides predictable billing dates for customers
   - Simplifies usage calculations and reporting

2. **Free Tier Efficiency**

   - Free tier users don't require Stripe customers or subscriptions
   - Only create Stripe resources when users actively choose to upgrade
   - Keeps Stripe dashboard clean and focused on paying customers

3. **Frictionless Upgrades**
   - Seamless transition from free to paid
   - Transparent upgrade process with payment method collection upfront
   - Clear visibility into usage and quotas

## System Overview

Unkey's Stripe billing integration manages user subscriptions through a tiered pricing model, with support for legacy usage-based pricing. The system handles payment methods, trials, subscription management, and customer portals.

The high-level user flow is as follows:

```
┌────────────┐     ┌────────────┐     ┌────────────┐     ┌────────────┐
│            │     │            │     │            │     │            │
│   Signup   │────►│  WorkOS    │────►│  Create    │────►│ Free Tier  │
│            │     │ Auth & Org │     │ Workspace  │     │            │
└────────────┘     └────────────┘     └────────────┘     └────────────┘
                                                                │
                                                                │
                                                                ▼
┌────────────┐     ┌────────────┐     ┌────────────┐     ┌────────────┐
│            │     │            │     │            │     │            │
│ Active Plan│◄────│ Upgrade    │◄────│ Add Payment│◄────│  User      │
│            │     │            │     │ Method     │     │  Action    │
└────────────┘     └────────────┘     └────────────┘     └────────────┘
```

## Key Components

1. **Workspace Billing Configuration**

   - `stripeCustomerId`: Links workspace to Stripe customer
   - `stripeSubscriptionId`: Links workspace to Stripe subscription
   - `tier`: Current plan tier (free, pro, etc.)
   - `quota`: Usage limits (primarily `requestsPerMonth`)

2. **Tiered Products**

   - Set of products with increasing request quotas
   - Clear upgrade/downgrade paths between plans
   - Price points displayed with monthly pricing

3. **Stripe Integration**

   - Payment setup with checkout sessions
   - Subscription management
   - Customer portal access
   - Billing management

4. **Usage Tracking**
   - Monitors current usage against quota
   - Displays percentage used
   - Combines verification and ratelimit requests

## Technical Implementation

### Stripe Environment Configuration

To enable Stripe billing functionality in Unkey, you need to configure the following environment variables:

1. **`STRIPE_SECRET_KEY`**

   - Your Stripe API secret key (begins with "sk\_")
   - Used for authenticating server-side API calls to Stripe
   - Example: `STRIPE_SECRET_KEY=sk_test_51MpJhKLoBBjyJTsUAbcXYZ...`

2. **`STRIPE_PRODUCT_IDS_PRO`**
   - Comma-separated list of Stripe product IDs representing your Pro tier plans
   - The order does not matter. Displayed products will be sorted by their cost.
   - Example: `STRIPE_PRODUCT_IDS_PRO=prod_OS1AbC2DeF,prod_OS3GhI4JkL,prod_OS5MnO6PqR`

The system is designed to gracefully handle missing Stripe configuration, displaying appropriate UI messages instead of errors when these variables are not set.

### Workspace Database Schema

The workspace schema includes:

```typescript
workspaces {
  id: string
  orgId: string
  stripeCustomerId: string | null
  stripeSubscriptionId: string | null
  tier: string
  subscriptions: object | null  // Legacy
  quotas: {
    requestsPerMonth: number
    logsRetentionDays: number
    auditLogsRetentionDays: number
    team: boolean
  }
}
```

## User Flows

### Adding a Payment Method

Before starting a subscription, users must add a payment method:

1. User clicks "Add payment method"
2. System creates a Stripe Checkout session in "setup" mode
3. User is redirected to Stripe to enter payment details
4. Upon completion, user is redirected back to billing page
5. The system associates the payment method with the customer
6. Customer ID is stored in the workspace record

### Starting a Subscription

Once a payment method is available:

1. User selects a plan and clicks "Upgrade"
2. System checks if user has a customer ID:
   - If not, creates a checkout session for payment method collection first
   - If yes, creates a subscription with the selected product
3. Subscription details are stored in the workspace record
4. Quota is updated based on the product metadata
5. Audit log entry is created for the subscription change

### Changing Plans

Users can change between available plans:

1. User selects a different plan and clicks "Change"
2. Confirmation dialog shows what will change
3. Upon confirmation, system:
   - Updates the subscription with the new product
   - Prorates charges automatically
   - Updates workspace tier and quota
   - Creates an audit log entry
4. UI updates to show the new plan as selected

### Cancelling a Subscription

Users can cancel their subscription:

1. User clicks "Cancel Plan"
2. Confirmation dialog explains implications
3. Upon confirmation, system:
   - Cancels the subscription with Stripe
   - Nullifies the subscription ID in the workspace
   - Resets quota to free tier levels
   - Creates an audit log entry
4. UI updates to show free tier status

## Billing Portal

For additional billing operations, users can access the Stripe Billing Portal:

1. User clicks "Open Portal"
2. System creates a portal session with the customer ID
3. User is redirected to Stripe portal
4. User can manage payment methods, view invoices, etc.
5. Upon completion, user is redirected back to the app

## Legacy Plans

The system handles users who were on legacy usage-based pricing:

1. Detects legacy subscription data in the workspace
2. Shows alternative billing UI for these users
3. Provides contact option to migrate to new pricing tiers
4. Maintains backward compatibility while encouraging migration

## Implementation Notes

### Product Metadata

Products in Stripe contain crucial metadata:

- `quota_requests_per_month`: Maximum API requests allowed
- `quota_logs_retention_days`: How long logs are retained
- `quota_audit_logs_retention_days`: How long audit logs are retained

### Usage Calculation

Usage is calculated as:

- Combined total of valid key verifications and ratelimits
- Reset at the beginning of each calendar month
- Displayed as both raw numbers and percentage of quota
